home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 001-025 / scopedisk4 / macfont / convert.c < prev    next >
C/C++ Source or Header  |  1995-03-18  |  6KB  |  310 lines

  1. /*
  2.  * Macintosh font conversion program
  3.  * (C)1987 Rico Mariani
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <exec/types.h>
  8. #include <exec/nodes.h>
  9. #include <libraries/diskfont.h>
  10.  
  11. #define HUNK_HEADER  0x3f3
  12. #define HUNK_CODE    0x3e9
  13. #define HUNK_RELOC32 0x3ec
  14. #define HUNK_END     0x3f2
  15.  
  16. typedef struct {
  17.     UBYTE FontType;
  18.     UBYTE Padding;
  19.     UWORD FirstChar;
  20.     UWORD LastChar;
  21.     UWORD WidMax;
  22.     WORD  KernMax;
  23.     WORD  NDescent;
  24.     UWORD FRectWidth;
  25.     UWORD FRectHeight;
  26.     UWORD OWTLoc;
  27.     UWORD Ascent;
  28.     UWORD Descent;
  29.     UWORD Leading;
  30.     UWORD RowWords;
  31. } FHEADER;
  32.  
  33. unsigned char *BitImage;
  34. unsigned short LocTable[260];
  35. unsigned short OWTable[260];
  36. FILE *f;
  37.  
  38. char *rindex();
  39. void *malloc();
  40.  
  41. main(argc,argv)
  42. int argc;
  43. char *argv[];
  44. {
  45.     int i,j,c;
  46.     FHEADER h;
  47.     ULONG RowBytes;
  48.     ULONG num_chars, fontName, fontData, fontLoc, fontSpace;
  49.     ULONG fontKern, fontEnd, fontLength;
  50.     ULONG IStart, IEnd, CWidth, OW, Offset, Kern;
  51.     ULONG uc, lock;
  52.     char *s, buf[128];
  53.     WORD entries, size;
  54.     int padbytes;
  55.  
  56.     if(argc != 2) {
  57.         fprintf(stderr,"Usage: %s fontname\n",argv[0]);
  58.         exit(1);
  59.     }
  60.  
  61.     s = rindex(argv[1],'.');
  62.     if (!s) {
  63.         fprintf(stderr,"Error fontname must be of the form:\n");
  64.         fprintf(stderr,"\tname.pointsize\n");
  65.         exit(1);
  66.     }
  67.  
  68.     f = fopen(argv[1],"r");
  69.     if (!f){
  70.         fprintf(stderr,"Error can't open file '%s'\n",argv[1]);
  71.         exit(1);
  72.     }
  73.  
  74.     fread( &h, sizeof(h), 1, f);
  75.  
  76.     printf("Font Data for %s:\n",argv[1]);
  77.     *s = '\0'; /* remove the suffix */
  78.     printf("\tChars %d to %d\n",h.FirstChar, h.LastChar);
  79.     printf("\tFont Rectangle (W,H) = (%d,%d)\n" ,
  80.         h.FRectWidth, h.FRectHeight);
  81.     printf("\tAscent = %d,  Descent = %d,  Leading = %d\n",
  82.         h.Ascent, h.Descent, h.Leading);
  83.  
  84.     RowBytes = 2*h.RowWords;
  85.  
  86.     BitImage = malloc(h.FRectHeight * RowBytes);
  87.     if (!BitImage) {
  88.         printf("Error, no memory for bit image\n");
  89.         exit(-1);
  90.     }
  91.  
  92.     fread(BitImage, h.FRectHeight * RowBytes, 1, f);
  93.  
  94.     for(i = h.FirstChar; i <= h.LastChar+2; i++) {
  95.         uc = fgetc(f);
  96.         LocTable[i] = uc << 8 | fgetc(f);
  97.     }
  98.  
  99.     for(i = h.FirstChar; i <= h.LastChar+2; i++) {
  100.         uc = fgetc(f);
  101.         OWTable[i] = uc << 8 | fgetc(f);
  102.     }
  103.  
  104.     fclose(f);
  105.  
  106.     sprintf(buf,"fonts:%s",argv[1]);
  107.     lock = CreateDir(buf);
  108.     if (lock) UnLock(lock);
  109.  
  110.     sprintf(buf,"fonts:%s/%d",argv[1],h.FRectHeight);
  111.     f = fopen(buf,"w");
  112.     if (!f) {
  113.         fprintf(stderr,"Error, can't open '%s' for write\n",buf);
  114.         exit(1);
  115.     }
  116.  
  117.     /* compute offsets into the code hunk */
  118.  
  119.     num_chars  = h.LastChar - h.FirstChar + 2;
  120.     fontName   = 0x1a;
  121.     fontData   = 0x6e;
  122.     fontLoc    = fontData  + RowBytes * h.FRectHeight;
  123.     fontSpace  = fontLoc   + (num_chars<<2);
  124.     fontKern   = fontSpace + (num_chars<<1);
  125.     fontEnd    = fontKern  + (num_chars<<1);
  126.  
  127.     /* long word align fontEnd */
  128.     padbytes = 0;
  129.     while (fontEnd & 3) {
  130.         padbytes++;
  131.         fontEnd++;
  132.     }
  133.     fontLength = fontEnd   - 0x3a;             /* the font: label */
  134.  
  135.     outL(HUNK_HEADER);
  136.     outL(0);        /* no hunk names */
  137.     outL(1);        /* Size of hunk table */
  138.     outL(0);        /* First Hunk */
  139.     outL(0);        /* Last Hunk */
  140.     outL(fontEnd>>2);    /* Size of Hunk 0 */
  141.  
  142.     outL(HUNK_CODE);
  143.     outL(fontEnd>>2);    /* Size of this hunk */
  144.  
  145.     /* now here comes the data for the hunk */
  146.     /* this first part is in case someone tries to run this */
  147.  
  148.     outW(0x7000);        /* MOVEQ.L #0,D0 */
  149.     outW(0x4e75);        /* RTS */
  150.  
  151.     outL(0);        /* ln_Succ */
  152.     outL(0);        /* ln_Pred */
  153.     outB(NT_FONT);        /* ln_Type */
  154.     outB(0);        /* ln_Pri  */
  155.     outL(0x1a);        /* ln_Name -- will be relocated */
  156.     outW(DFH_ID);        /* FileID */
  157.     outW(1);        /* Revision */
  158.     outL(0);        /* Segment */
  159.  
  160. /* fontName: */
  161.  
  162.     outZ(MAXFONTNAME);    /* output 32 zeros */
  163.  
  164. /* font: */
  165.  
  166.     outL(0);        /* ln_Succ */
  167.     outL(0);        /* ln_Pred */
  168.     outB(NT_FONT);        /* ln_Type */
  169.     outB(0);        /* ln_Pri  */
  170.     outL(0x1a);        /* ln_Name -- will be relocated */
  171.     outL(0);        /* mn_ReplyPort */
  172.     outW(fontLength);    /* nm_Length */
  173.     outW(h.FRectHeight);    /* tf_YSize */
  174.     outB(0);        /* tf_Style */
  175.     outB(0x62);        /* tf_Flags */
  176.     outW(h.FRectWidth);    /* tf_XSize */
  177.     outW(h.Ascent);        /* ft_BaseLine */
  178.     outW(1);        /* tf_BoldSmear */
  179.     outW(0);        /* tf_Accessors */
  180.     outB(h.FirstChar);    /* tf_LoChar */
  181.     outB(h.LastChar);    /* tf_HiChar */
  182.     outL(fontData);        /* tf_CharData */
  183.     outW(RowBytes);        /* tf_Modulo */
  184.     outL(fontLoc);        /* tf_CharLoc */
  185.     outL(fontSpace);    /* tf_CharSpace */
  186.     outL(fontKern);        /* tf_CharKern */
  187.  
  188. /* fontData: */
  189.  
  190.     fwrite(BitImage, RowBytes * h.FRectHeight, 1, f);
  191.  
  192. /* fontLoc: */
  193.  
  194.     /* note that there is an extra character in every font on both  */
  195.     /* that Amiga and the Mac which is used when a character not in */
  196.     /* the font is requested */
  197.  
  198.     for (i=h.FirstChar; i<= h.LastChar + 1; i++) {
  199.         if (OWTable[i] == -1)
  200.             c = h.LastChar+1;
  201.         else
  202.             c = i;
  203.  
  204.         IStart = LocTable[c];
  205.         IEnd   = LocTable[c+1];
  206.         outW(IStart);
  207.         outW(IEnd-IStart);
  208.     }
  209.  
  210. /* fontSpace: */
  211.  
  212.     for (i=h.FirstChar; i<= h.LastChar+1; i++) {
  213.         OW = OWTable[i];
  214.         if (OWTable[i] == -1) OW = OWTable[h.LastChar+1];
  215.  
  216.         CWidth = OW & 0xff;
  217.         outW(CWidth);
  218.     }
  219.  
  220. /* fontKern: */
  221.  
  222.     for (i=h.FirstChar; i<= h.LastChar+1; i++) {
  223.         OW = OWTable[i];
  224.         if (OWTable[i] == -1) OW = OWTable[h.LastChar+1];
  225.  
  226.         Offset = OW >> 8;
  227.         Kern = h.KernMax + Offset;
  228.         outW(Kern);
  229.  
  230.     }
  231.  
  232.     for (i=0;i<padbytes;i++) outB(0);
  233.  
  234. /* fontEnd: */
  235.  
  236.     outL(HUNK_RELOC32);
  237.     outL(6);        /* of relocates number in this hunk */
  238.     outL(0);        /* hunk 0 */
  239.     outL(0x0e);        /* relocate reference to fontName: 1st */
  240.     outL(0x44);        /* relocate reference to fontName: 2nd */
  241.     outL(0x5c);        /* relocate reference to fontData:  */
  242.     outL(0x62);        /* relocate reference to fontLoc:   */
  243.     outL(0x66);        /* relocate reference to fontSpace: */
  244.     outL(0x6a);        /* relocate reference to fontKern:  */
  245.     outL(0);        /* zero to mark end */
  246.     outL(HUNK_END);
  247.  
  248.     fclose(f);
  249.  
  250.     sprintf(buf,"fonts:%s.font",argv[1]);
  251.     f = fopen(buf,"r+");
  252.     if (!f) {
  253.         f = fopen(buf,"w+");
  254.         if (!f) {
  255.             fprintf(stderr,"Error, can't create font header\n");
  256.             exit(1);
  257.         }
  258.         outW(0x0f00);    /* font header */
  259.         outW(0x0000);    /* number of font items */
  260.     }
  261.  
  262.     fseek(f,2,0);
  263.  
  264.     fread(&entries,2,1,f);
  265.  
  266.     for (i=0;i<entries;i++) {
  267.         fseek(f, 4+(260*i)+256, 0);
  268.         fread(&size,2,1,f);    /* read in ysize */
  269.         if (size == h.FRectHeight) {
  270.             printf("Amiga font of this size already exists");
  271.             printf("... overwritten\n");
  272.             exit(1);
  273.         }
  274.     }
  275.  
  276.     fseek(f,2,0);
  277.     outW(++entries);
  278.     fseek(f,0,2);
  279.     sprintf(buf,"%s/%d",argv[1],h.FRectHeight);
  280.     fwrite(buf,strlen(buf),1,f);
  281.     for (i=strlen(buf);i<256;i++) fputc(0,f);
  282.     outW(h.FRectHeight);
  283.     outB(0);
  284.     outB(0x62);
  285.     fclose(f);
  286. }
  287.  
  288. outB(b)
  289. {
  290.     fputc(b,f);
  291. }
  292.  
  293. outW(w)
  294. {
  295.     fputc(w>>8,f);
  296.     fputc(w&0xff,f);
  297. }
  298.  
  299. outL(l)
  300. {
  301.     fwrite(&l,4,1,f);
  302. }
  303.  
  304. outZ(n)
  305. {
  306.     int i;
  307.  
  308.     for (i=n;--i>=0;) fputc(0,f);
  309. }
  310.